home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
pascal
/
tptc17tc.zip
/
UNSQ.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1988-03-25
|
24KB
|
965 lines
(*
DEARC.PAS - Program to extract all files from an archive created by version
5.12 or earlier of the ARC utility.
*** ORIGINAL AUTHOR UNKNOWN ***
*)
Program DearcSQ;
{$R-}
{$U-}
{$C-}
{$K-}
const
BLOCKSIZE = 128;
arcmarc = 26; { special archive marker }
arcver = 9; { max archive header version code }
strlen = 100; { standard string length }
fnlen = 12; { file name length - 1 }
const
crctab : array [0..255] of integer =
( $0000, $C0C1, $C181, $0140, $C301, $03C0, $0280, $C241,
$C601, $06C0, $0780, $C741, $0500, $C5C1, $C481, $0440,
$CC01, $0CC0, $0D80, $CD41, $0F00, $CFC1, $CE81, $0E40,
$0A00, $CAC1, $CB81, $0B40, $C901, $09C0, $0880, $C841,
$D801, $18C0, $1980, $D941, $1B00, $DBC1, $DA81, $1A40,
$1E00, $DEC1, $DF81, $1F40, $DD01, $1DC0, $1C80, $DC41,
$1400, $D4C1, $D581, $1540, $D701, $17C0, $1680, $D641,
$D201, $12C0, $1380, $D341, $1100, $D1C1, $D081, $1040,
$F001, $30C0, $3180, $F141, $3300, $F3C1, $F281, $3240,
$3600, $F6C1, $F781, $3740, $F501, $35C0, $3480, $F441,
$3C00, $FCC1, $FD81, $3D40, $FF01, $3FC0, $3E80, $FE41,
$FA01, $3AC0, $3B80, $FB41, $3900, $F9C1, $F881, $3840,
$2800, $E8C1, $E981, $2940, $EB01, $2BC0, $2A80, $EA41,
$EE01, $2EC0, $2F80, $EF41, $2D00, $EDC1, $EC81, $2C40,
$E401, $24C0, $2580, $E541, $2700, $E7C1, $E681, $2640,
$2200, $E2C1, $E381, $2340, $E101, $21C0, $2080, $E041,
$A001, $60C0, $6180, $A141, $6300, $A3C1, $A281, $6240,
$6600, $A6C1, $A781, $6740, $A501, $65C0, $6480, $A441,
$6C00, $ACC1, $AD81, $6D40, $AF01, $6FC0, $6E80, $AE41,
$AA01, $6AC0, $6B80, $AB41, $6900, $A9C1, $A881, $6840,
$7800, $B8C1, $B981, $7940, $BB01, $7BC0, $7A80, $BA41,
$BE01, $7EC0, $7F80, $BF41, $7D00, $BDC1, $BC81, $7C40,
$B401, $74C0, $7580, $B541, $7700, $B7C1, $B681, $7640,
$7200, $B2C1, $B381, $7340, $B101, $71C0, $7080, $B041,
$5000, $90C1, $9181, $5140, $9301, $53C0, $5280, $9241,
$9601, $56C0, $5780, $9741, $5500, $95C1, $9481, $5440,
$9C01, $5CC0, $5D80, $9D41, $5F00, $9FC1, $9E81, $5E40,
$5A00, $9AC1, $9B81, $5B40, $9901, $59C0, $5880, $9841,
$8801, $48C0, $4980, $8941, $4B00, $8BC1, $8A81, $4A40,
$4E00, $8EC1, $8F81, $4F40, $8D01, $4DC0, $4C80, $8C41,
$4400, $84C1, $8581, $4540, $8701, $47C0, $4680, $8641,
$8201, $42C0, $4380, $8341, $4100, $81C1, $8081, $4040 );
type
longtype = record { used to simulate long (4 byte) integers }
l, h : integer
end;
strtype = string[strlen];
fntype = array [0..fnlen] of char;
buftype = array [1..BLOCKSIZE] of byte;
heads = record
name : fntype;
size : longtype;
date : integer;
time : integer;
crc : integer;
length : longtype
end;
var
hdrver : byte;
arcfile : file;
arcbuf : buftype;
arcptr : integer;
arcname : strtype;
endfile : boolean;
extfile : file;
extbuf : buftype;
extptr : integer;
extname : strtype;
{ definitions for unpack }
Const
DLE = $90;
Var
state : (NOHIST, INREP);
crcval : integer;
size : real;
lastc : integer;
{ definitions for unsqueeze }
Const
ERROR = -1;
SPEOF = 256;
NUMVALS = 256; { 1 less than the number of values }
Type
nd = record
child : array [0..1] of integer
end;
Var
node : array [0..NUMVALS] of nd;
bpos : integer;
curin : integer;
numnodes : integer;
{ definitions for uncrunch }
Const
TABSIZE = 4096;
TABSIZEM1 = 4095;
NO_PRED = $FFFF;
EMPTY = $FFFF;
Type
entry = record
used : boolean;
next : integer;
predecessor : integer;
follower : byte
end;
Var
stack : array [0..TABSIZEM1] of byte;
sp : integer;
string_tab : array [0..TABSIZEM1] of entry;
Var
code_count : integer;
code : integer;
firstc : boolean;
oldcode : integer;
finchar : integer;
inbuf : integer;
outbuf : integer;
newhash : boolean;
{ definitions for dynamic uncrunch }
Const
Crunch_BITS = 12;
Squash_BITS = 13;
HSIZE = 8192;
INIT_BITS = 9;
FIRST = 257;
CLEAR = 256;
HSIZEM1 = 8191;
BITSM1 = 12;
RMASK : array[0..8] of byte =
($00, $01, $03, $07, $0f, $1f, $3f, $7f, $ff);
Var
bits,
n_bits,
maxcode : integer;
prefix : array[0..HSIZEM1] of integer;
suffix : array[0..HSIZEM1] of byte;
buf : array[0..BITSM1] of byte;
clear_flg : integer;
stack1 : array[0..HSIZEM1] of byte;
free_ent : integer;
maxcodemax : integer;
offset,
sizex : integer;
firstch : boolean;
procedure abortme(s : strtype);
{ terminate the program with an error message }
begin
writeln('ABORT: ', s);
halt;
end; (* proc abortme *)
function fn_to_str(var fn : fntype) : strtype;
{ convert strings from C format (trailing 0) to Turbo Pascal format (leading
length byte). }
var s : strtype;
i : integer;
begin
s := '';
i := 0;
while fn[i] <> #0 do begin
s := s + fn[i];
i := i + 1
end;
fn_to_str := s
end; (* func fn_to_str *)
function unsigned_to_real(u : integer) : real;
{ convert unsigned integer to real }
{ note: INT is a function that returns a REAL!!!}
begin
if u >= 0 then
unsigned_to_real := Int(u)
else
if u = $8000 then
unsigned_to_real := 32768.0
else
unsigned_to_real := 65536.0 + u
end; (* func unsigned_to_real *)
function long_to_real(l : longtype) : real;
{ convert longtype integer to a real }
{ note: INT is a function that returns a REAL!!! }
var r : real;
s : (posit, NEG);
const rcon = 65536.0;
begin
if l.h >= 0 then begin
r := Int(l.h) * rcon;
s := posit {notice: no ";" here}
end
else begin
s := NEG;
if l.h = $8000 then
r := rcon * rcon
else
r := Int(-l.h) * rcon
end;
r := r + unsigned_to_real(l.l);
if s = NEG then
long_to_real := -r
else
long_to_real := r
end; (* func long_to_real *)
procedure Read_Block;
{ read a block from the archive file }
begin
if EOF(arcfile) then
endfile := TRUE
else
BlockRead(arcfile, arcbuf, 1);
arcptr := 1
end; (* proc read_block *)
procedure Write_Block;
{ write a block to the extracted file }
begin
BlockWrite(extfile, extbuf, 1);
extptr := 1
end; (* proc write_block *)
procedure open_arc;
{ open the archive file for input processing }
begin
{$I-} assign(arcfile, arcname); {$I+}
if ioresult <> 0 then
abortme('Cannot open archive file.');
{$I-} reset(arcfile); {$I+}
if ioresult <> 0 then
abortme('Cannot open archive file.');
endfile := FALSE;
Read_Block
end; (* proc open_arc *)
procedure open_ext;
{ open the extracted file for writing }
begin
{$I-} assign(extfile, extname); {$I+}
if ioresult <> 0 then
abortme('Cannot open extract file.');
{$I-} rewrite(extfile); {$I+}
if ioresult <> 0 then
abortme('Cannot open extract file.');
extptr := 1;
end; (* proc open_ext *)
function get_arc : byte;
{ read 1 character from the archive file }
begin
if endfile then
get_arc := 0
else begin
get_arc := arcbuf[arcptr];
if arcptr = BLOCKSIZE then
Read_Block
else
arcptr := arcptr + 1
end
end; (* func get_arc *)
procedure put_ext(c : byte);
{ write 1 character to the extracted file }
begin
extbuf[extptr] := c;
if extptr = BLOCKSIZE then
Write_Block
else
extptr := extptr + 1
end; (* proc put_ext *)
procedure close_arc;
{ close the archive file }
begin
close(arcfile)
end; (* proc close_arc *)
procedure close_ext;
{ close the ext